package com.guoxue.auth;

import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;

import javax.servlet.FilterChain;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;
import org.springframework.web.filter.OncePerRequestFilter;

import com.alibaba.fastjson.JSONObject;
import com.guoxue.consts.SCUser;
import com.guoxue.dao.impl.UserDaoImpl;
import com.guoxue.domain.BackUserVo;
import com.guoxue.domain.UserVo;
import com.guoxue.util.RedisUtil;
import com.guoxue.util.codeSwitch.khb;

import redis.clients.jedis.Jedis;

public class AuthFilter extends OncePerRequestFilter {
	String basePath;
	private UserDaoImpl userDao;
	private GXTokenSevice gxTokenSevice;
	String urlBate = "";// 当前使用密钥的版本号

	@Override
	protected void initFilterBean() throws ServletException {
		super.initFilterBean();
		ServletContext servletContext = getServletContext();
		WebApplicationContext webApplicationContext = WebApplicationContextUtils
				.getRequiredWebApplicationContext(servletContext);
		this.userDao = (UserDaoImpl) webApplicationContext.getBean("userDaoImpl");
		this.gxTokenSevice = (GXTokenSevice) webApplicationContext.getBean("gxTokenSevice");
		// 加载当前密钥的版本号
		InputStream in = this.getServletContext().getResourceAsStream("/WEB-INF/classes/jdbc.properties");
		Properties pro = new Properties();
		try {
			pro.load(in);
			urlBate = pro.getProperty("valisession");
			in.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	@Override
	protected void doFilterInternal(HttpServletRequest req, HttpServletResponse resp, FilterChain chain)
			throws ServletException, IOException {
		String requestUrl = req.getRequestURI();// 获取当前请求路径
		HttpSession session = req.getSession(true);// 获取当前session
		String sessionId = req.getRequestedSessionId();
		String sessionId2 = req.getSession().getId();
		/*---------------检测是否是“非拦截路径”----------------------*/
		khb.ts.function(); // 拦截接口的整理+整理后的测试
		khb.ta.function(); // 中途封号的验证及限制
		khb.ta.function(); // OSS给url时效token的时候，需要前端维护时效性
		khb.ta.function(); // oss改成url静态连接需要前端同步维护
		if (requestUrl.indexOf(".do") <= 0 || requestUrl.indexOf("login.do") > 0 || requestUrl.indexOf("logout.do") > 0
				|| requestUrl.indexOf("register.do") > 0 || requestUrl.indexOf("/back/logout.do") > 0
				|| requestUrl.indexOf("/back/login.do") > 0 || requestUrl.indexOf("captcha-image.do") > 0
				|| requestUrl.indexOf("sendMessage.do") > 0 || requestUrl.indexOf("checkForUpdate.do") > 0
				|| requestUrl.indexOf("publish") > 0 || requestUrl.indexOf("getTokenForUrl.do") > 0
				|| requestUrl.indexOf("downloadForUpdate.do") > 0 || requestUrl.indexOf("resourceUpload.do") > 0
				|| requestUrl.indexOf("pay/callBackAliPay.do") > 0 || requestUrl.indexOf("pay/callBackWXPay.do") > 0
				|| requestUrl.indexOf("createUserName.do") > 0 || requestUrl.indexOf("/sharePage.do") > 0 // createUserName.do需在线上环境时关闭，具体看重构后代码逻辑
				|| requestUrl.indexOf("/share") > 0 || requestUrl.indexOf("pay/getBankOrderInfo.do") > 0
				|| requestUrl.indexOf("pay/callBackBankPay.do") > 0 || requestUrl.indexOf("getServerInfo.do") > 0
				|| requestUrl.indexOf("sendDebug.do") > 0) {
			chain.doFilter(req, resp);
			return;
		}
		/*---------------检测是否来自后端管理的请求----------------------*/
		BackUserVo backuser = (BackUserVo) session.getAttribute("Back_user");
		if (backuser != null) {
			chain.doFilter(req, resp);
			return;
		}
		/*---------------检测来自前端接口调用的请求----------------------*/
		/**
		 * 1.判断请求是否合法GxToken
		 * 2.判断session是否存在
		 * 3.校验请求用户身份是否合法
		 * */
		String gxToken=req.getHeader("GxToken+");
		JSONObject obj = new JSONObject();
		obj.put("data", "");
		obj.put("code", "400");
		if (gxToken == null || "".equals(gxToken)) {
			obj.put("message", "Your operation is illegal.");
			resp.getWriter().write(obj.toJSONString());
			return;
		} else {
			gxToken = gxToken.substring(0, gxToken.length() - 1);
			/* 判断是否有用户信息 */
			khb.ta.function();// 回复：zt在登录成功后是否存用户信息到session
			/* 验证请求的合法性，是否伪造登录1.首先需要验证版本是否一致2.再验证信息是否一致 */
			String gxResult = this.gxTokenSevice.getAccessKey(gxToken);
			String[] a = gxResult.split("\\|");
			String transmitSession = "";// 传递参数过来的sessionId
			String transmitUid = "";// 传递参数过来的的用户ID
			// String creatTime="";//传递参数过来的用户登录的时间,目前暂时未设定用途，备用字段
			String transmitVali = "";// 传递参数过来使用密钥的版本
			try {
				transmitSession = a[0];
				transmitUid = a[1];
				// creatTime=a[2];
				transmitVali = a[3];
				if (!transmitVali.equals(urlBate)) {
					obj.put("message", "You need to update to the new version");
					resp.getWriter().write(obj.toJSONString());
					return;
				}
			} catch (Exception e) {
				obj.put("message", "out of date");
				resp.getWriter().write(obj.toJSONString());
				return;
			}
			// 验证版本是否一致
			// 比较传递的信息和当前的信息是否一致
			if (!sessionId.equals(transmitSession)) {
				obj.put("message", "Your operation is illegal.");
				resp.getWriter().write(obj.toJSONString());
				return;
			}
			// 验证是否伪造token(与存储在session中的的token比较)
			String ownToken = (String) session.getAttribute("GxToken");
			if (!gxToken.equals(ownToken)) {
				obj.put("message", "Your operation is illegal.");
				resp.getWriter().write(obj.toJSONString());
				return;
			}
			req.setAttribute(SCUser.AUTH_UID_KEYNAME, transmitUid);
			chain.doFilter(req, resp);
			return;
		}
	}
}
